import Point from './Point.js';
import * as utils from './utils.js';

// ================== base methods
export function create(el, dimensions, padding, ratio = 1) { //eslint-disable-line
    // console.log('[Matrix] create: ', ratio);
    // if (!el) return; // 防止找不到DOM节点报错
    let width, height;
    if (el && el.parentNode) {
        width = parseInt(getComputedStyle(el.parentNode).width, 10);
        height = parseInt(getComputedStyle(el.parentNode).height, 10);
    }
    let xMin = dimensions[0],
        xMax = dimensions[1],
        yMin = dimensions[2],
        yMax = dimensions[3],
        p = (100 - (typeof padding !== 'undefined' ? padding : 10)) / 100,
        scale = Math.min((width * p) / (xMax - xMin), (height * p) / (yMax - yMin)),
        offsX = width / 2 - (scale * (xMax - xMin)) / 2 - scale * xMin,
        offsY = height / 2 + (scale * (yMax - yMin)) / 2 + scale * yMin;

    if (!offsX) {
        offsX = 0;
    }
    if (!offsY) {
        offsY = 0;
    }
    if (!scale) {
        scale = 0;
    }
    // let matrix = new DOMMatrix();
    let svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),
        matrix = svg.createSVGMatrix();
    matrix = matrix.translate(offsX * ratio, offsY * ratio);
    matrix = matrix.scale(scale * ratio);
    matrix = matrix.flipY();
    return matrix;
}

export function getTranslation(matrix) {
    return new Point(matrix.e, matrix.f);
}

export function getRotation(matrix) {
    return degrees(Math.atan2(-matrix.b, matrix.a));
}

export function getScaling(matrix) {
    if (!matrix) return null;
    var sx = Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b);
    var sy = Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d);

    return new Point(sx, sy);
}

export function degrees(value) {
    value *= 180 / Math.PI;
    if (value < 0) value += 360;
    if (value > 360) value -= 360;
    return value;
}

export function getPixelRatio(context) { //eslint-disable-line
    if (!context) return 2;
    let backingStore =
        context.backingStorePixelRatio ||
        context.webkitBackingStorePixelRatio ||
        context.mozBackingStorePixelRatio ||
        context.msBackingStorePixelRatio ||
        context.oBackingStorePixelRatio ||
        context.backingStorePixelRatio ||
        1;
    if (utils.isMobile()) return 1;
    return 2 / backingStore;
    // // let rtn = (window.devicePixelRatio || 1) / backingStore;
    // // if (!rtn) rtn = 2;
    // // return (window.devicePixelRatio || 1) / backingStore;
    // console.log('[Matrix] getPixelRatio: ', backingStore);
    // return 1;
}

// ================== custom methods
const MIN_NUMBER = -Number.MAX_VALUE,
    MAX_NUMBER = Number.MAX_VALUE;
export function getCurrentMapDimensions(leftBottomP = [], rightTopP = [], dimensions, ratio = 1) {
    if (!leftBottomP) leftBottomP = [];
    if (!rightTopP) rightTopP = [];
    let xMin = dimensions ? dimensions[0] : leftBottomP.length ? MAX_NUMBER : -10000,
        xMax = dimensions ? dimensions[1] : rightTopP.length ? MIN_NUMBER : +10000,
        yMin = dimensions ? dimensions[2] : leftBottomP.length ? MAX_NUMBER : -10000,
        yMax = dimensions ? dimensions[3] : rightTopP.length ? MIN_NUMBER : +10000;

    if (!leftBottomP.x || !leftBottomP.y || !rightTopP.x || !rightTopP.y) return [xMin, xMax, yMin, yMax];
    xMin = leftBottomP.x;
    xMax = rightTopP.x;
    yMin = leftBottomP.y;
    yMax = rightTopP.y;
    ratio = 1; // todo: del ratio
    return [xMin * ratio, xMax * ratio, yMin * ratio, yMax * ratio];
}
export function getVehicleDimensions(model, vehicles = [], dimensions, ratio = 1) {
    if (!vehicles) vehicles = [];
    let xMin = dimensions ? dimensions[0] : vehicles.length ? MAX_NUMBER : -10000,
        xMax = dimensions ? dimensions[1] : vehicles.length ? MIN_NUMBER : +10000,
        yMin = dimensions ? dimensions[2] : vehicles.length ? MAX_NUMBER : -10000,
        yMax = dimensions ? dimensions[3] : vehicles.length ? MIN_NUMBER : +10000;

    if (!model) return [xMin, xMax, yMin, yMax];
    let r = Math.max(model.size.x, model.size.y) * 0.75;

    for (let i = 0; i < vehicles.length; i++) {
        let t = vehicles[i];
        if (t.tunedPos && t.tunedPos.x - r < xMin) xMin = t.tunedPos.x - r;
        if (t.tunedPos && t.tunedPos.x + r > xMax) xMax = t.tunedPos.x + r;
        if (t.tunedPos && t.tunedPos.y - r < yMin) yMin = t.tunedPos.y - r;
        if (t.tunedPos && t.tunedPos.y + r > yMax) yMax = t.tunedPos.y + r;
    }
    ratio = 1; 
    return [xMin * ratio, xMax * ratio, yMin * ratio, yMax * ratio];
}
export function getPathDimensions(paths = [], dimensions, ratio = 1) {
    if (!paths) paths = [];
    let xMin = dimensions ? dimensions[0] : paths && paths.length ? MAX_NUMBER : -10000,
        xMax = dimensions ? dimensions[1] : paths && paths.length ? MIN_NUMBER : +10000,
        yMin = dimensions ? dimensions[2] : paths && paths.length ? MAX_NUMBER : -10000,
        yMax = dimensions ? dimensions[3] : paths && paths.length ? MIN_NUMBER : +10000;

    for (let i = 0; i < paths.length; i++) {
        let path = paths[i];
        if (!path || !path.controlPoints || !path.controlPoints.length) continue;
        // var sp = path.startPoint();
        // var ep = path.endPoint();
        let sp = path && path.controlPoints ? path.controlPoints[0] : null;
        let ep = path && path.controlPoints ? path.controlPoints[path.controlPoints.length - 1] : null;
        if (!sp || !ep) return [xMin, xMax, yMin, yMax];

        if (sp.x < xMin) xMin = sp.x;
        if (sp.x > xMax) xMax = sp.x;
        if (sp.y < yMin) yMin = sp.y;
        if (sp.y > yMax) yMax = sp.y;

        if (ep.x < xMin) xMin = ep.x;
        if (ep.x > xMax) xMax = ep.x;
        if (ep.y < yMin) yMin = ep.y;
        if (ep.y > yMax) yMax = ep.y;
    }
    ratio = 1; // todo: del ratio
    return [xMin * ratio, xMax * ratio, yMin * ratio, yMax * ratio];
}
export function getContourDimensions(contours = [], dimensions, ratio = 1) {
    if (!contours) contours = [];
    let xMin = dimensions ? dimensions[0] : contours.length ? MAX_NUMBER : -10000,
        xMax = dimensions ? dimensions[1] : contours.length ? MIN_NUMBER : +10000,
        yMin = dimensions ? dimensions[2] : contours.length ? MAX_NUMBER : -10000,
        yMax = dimensions ? dimensions[3] : contours.length ? MIN_NUMBER : +10000;

    if (!contours || !contours.length) return [xMin, xMax, yMin, yMax];
    for (var i = 0; i < contours.length; i++) {
        if (!contours[i] || !contours[i].points || !contours[i].points.length) continue;
        for (var k = 0; k < contours[i].points.length; k++) {
            var p = contours[i].points[k];

            if (p.x < xMin) xMin = p.x;
            if (p.x > xMax) xMax = p.x;
            if (p.y < yMin) yMin = p.y;
            if (p.y > yMax) yMax = p.y;
        }
    }
    ratio = 1; 
    return [xMin * ratio, xMax * ratio, yMin * ratio, yMax * ratio];
}
